package com.rxyb.toolize.date;

import com.rxyb.toolize.date.enums.DateType;
import com.rxyb.toolize.date.enums.FormatDate;

import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.GregorianCalendar;

/**
 * @author YJH
 * @version 1.0
 * @description 时间操作
 * @date 2020/6/21 18:22
 */
public final class DateHandle implements Serializable {


    private static final long serialVersionUID = -16256037036032620L;

    /**
     * 今日还剩下多少秒
     *
     * @return
     */
    public static Integer endNextDayTime() {
        Calendar curDate = Calendar.getInstance();
        return (int) (DateHandleUtils.getCalender().getTimeInMillis() - curDate.getTimeInMillis()) / (1000);
    }

    /**
     * 今日还剩下多长时间
     * 计算: 时,分,秒
     *
     * @param type 类型
     * @return
     */
    public static Integer endNextDayTime(DateType type) {
        Calendar curDate = Calendar.getInstance();
        return (int) (DateHandleUtils.getCalender().getTimeInMillis() - curDate.getTimeInMillis()) / (1000 * type.getCalculate());
    }

    /**
     * 计算两个时间段相差多少秒
     *
     * @param beginDate 开始时间
     * @param endDate   结束时间
     * @return 秒
     */
    public static Long discrepancy(Long beginDate, Long endDate) {
        Long begin = DateHandleUtils.longToLocalDateTime(beginDate);
        Long end = DateHandleUtils.longToLocalDateTime(endDate);
        return (end - begin) / 1000;
    }


    /**
     * 计算两个时间段相差多少秒
     * 备注: 如果计算月或者年 请使用 DATE_YEAR 或者 DATE_MONTH
     *
     * @param beginDate 开始时间
     * @param endDate   结束时间
     * @param dateType  时间类型
     * @return
     */
    public static Long discrepancy(Long beginDate, Long endDate, DateType dateType) {
        // 年相差多少
        if (dateType.getIndex() == DateType.DATE_YEAR.getIndex()) {
            return Long.valueOf(DateTime.getYear(endDate) - DateTime.getYear(beginDate));
        }
        // 月相差多少
        if (dateType.getIndex() == DateType.DATE_MONTH.getIndex()) {
            int month = 0;
            Integer num = DateTime.getYear(endDate) - DateTime.getYear(beginDate);
            if (num > 0) {
                month = num * 12;
            }
            month += (DateTime.getMonth(endDate).getIndex() + 1) - (DateTime.getMonth(beginDate).getIndex() + 1);
            return Long.valueOf(month);
        }
        Long begin = DateHandleUtils.longToLocalDateTime(beginDate);
        Long end = DateHandleUtils.longToLocalDateTime(endDate);
        return (end - begin) / 1000 / dateType.getCalculate();
    }


    /**
     * 获取当前日期的偏移量-天
     *
     * @param days 偏移的数量
     * @return
     */
    public static Long dayPlusDay(int days) {
        return DateHandleUtils.parseDateToLong(LocalDate.now().plusDays(days), FormatDate.FORMAT_DATE_LONG.getValue());
    }

    /**
     * 获取当前日期的偏移量-天
     *
     * @param days       偏移的数量
     * @param formatDate 格式
     * @return
     */
    public static String dayPlusDay(int days, FormatDate formatDate) {
        if (formatDate.getValue().trim().length() > 11) {
            return LocalDateTime.now().plusDays(days).format(DateTimeFormatter.ofPattern(formatDate.getValue()));
        }
        return LocalDate.now().plusDays(days).format(DateTimeFormatter.ofPattern(formatDate.getValue()));
    }


    /**
     * 获取某个日期的偏移量-天
     *
     * @param date 时间
     * @param days 偏移的数量
     * @return
     */
    public static Long dayPlusDay(Long date, int days) {
        if (date > 100000000L) {
            LocalDateTime localDateTime = LocalDateTime.parse(String.valueOf(date), DateTimeFormatter.ofPattern(FormatDate.getValue(date.toString()).getValue())).plusHours(days);
            return DateHandleUtils.parseDateToLong(localDateTime, FormatDate.FORMAT_TIME_LONG.getValue());
        }
        return DateHandleUtils.parseDateToLong(LocalDate.parse(String.valueOf(date),
                DateTimeFormatter.ofPattern(FormatDate.getValue(date.toString()).getValue())).plusDays(days), FormatDate.FORMAT_DATE_LONG.getValue());
    }

    /**
     * 获取某个日期的偏移量-天
     *
     * @param date 时间
     * @param days 偏移的数量
     * @return
     */
    public static String dayPlusDay(String date, int days) {
        if (date.trim().length() > 11) {
            LocalDateTime localDateTime = LocalDateTime.parse(date, DateTimeFormatter.ofPattern(FormatDate.getValue(date).getValue())).plusHours(days);
            return DateHandleUtils.parseDate(localDateTime, FormatDate.FORMAT_TIME_LONG.getValue());
        }
        return DateHandleUtils.parseDate(LocalDate.parse(date, DateTimeFormatter.ofPattern(FormatDate.getValue(date).getValue())).plusDays(days), FormatDate.FORMAT_DATE_LONG.getValue());
    }

    /**
     * 获取当前日期的偏移量-月
     *
     * @param months 偏移的数量
     * @return
     */
    public static Long dayPlusMonth(int months) {
        return DateHandleUtils.parseDateToLong(LocalDate.now().plusMonths(months), FormatDate.FORMAT_DATE_LONG.getValue());
    }

    /**
     * 获取当前日期的偏移量-月
     *
     * @param months     偏移的数量
     * @param formatDate 格式
     * @return
     */
    public static String dayPlusMonth(int months, FormatDate formatDate) {
        if (formatDate.getValue().trim().length() > 11) {
            return DateHandleUtils.parseDate(LocalDateTime.now().plusMonths(months), formatDate.getValue());
        }
        return DateHandleUtils.parseDate(LocalDate.now().plusMonths(months), formatDate.getValue());
    }

    /**
     * 获取当前日期的偏移量-月
     *
     * @param date   时间
     * @param months 偏移的数量
     * @return
     */
    public static Long dayPlusMonth(Long date, int months) {
        if (date > 100000000L) {
            LocalDateTime localDateTime = LocalDateTime.parse(String.valueOf(date), DateTimeFormatter.ofPattern(FormatDate.getValue(date.toString()).getValue())).plusMonths(months);
            return DateHandleUtils.parseDateToLong(localDateTime, FormatDate.FORMAT_TIME_LONG.getValue());
        }
        return DateHandleUtils.parseDateToLong(LocalDate.parse(String.valueOf(date), DateTimeFormatter.ofPattern(FormatDate.getValue(date.toString()).getValue())).plusMonths(months), FormatDate.FORMAT_DATE_LONG.getValue());
    }


    /**
     * 获取当前日期的偏移量-月
     *
     * @param date   时间（基本格式都能转换）
     * @param months 偏移的数量
     * @return
     */
    public static Long dayPlusMonth(String date, int months) {
        if (date.trim().length() > 11) {
            LocalDateTime localDateTime = LocalDateTime.parse(date, DateTimeFormatter.ofPattern(FormatDate.getValue(date).getValue())).plusMonths(months);
            return DateHandleUtils.parseDateToLong(localDateTime, FormatDate.FORMAT_TIME_LONG.getValue());
        }
        return DateHandleUtils.parseDateToLong(LocalDate.parse(date, DateTimeFormatter.ofPattern(FormatDate.getValue(date).getValue()))
                .plusMonths(months), FormatDate.FORMAT_DATE_LONG.getValue());
    }

    /**
     * 获取当前日期的偏移量-年
     *
     * @param years 偏移数量
     * @return
     */
    public static Long dayPlusYear(int years) {
        return DateHandleUtils.parseDateToLong(LocalDate.now().plusYears(years), FormatDate.FORMAT_DATE_LONG.getValue());
    }


    /**
     * 获取当前日期的偏移量-年
     *
     * @param years      偏移数量
     * @param formatDate 格式
     * @return
     */
    public static String dayPlusYear(int years, FormatDate formatDate) {
        if (formatDate.getValue().length() > 11) {
            return DateHandleUtils.parseDate(LocalDateTime.now().plusYears(years), formatDate.getValue());
        }
        return DateHandleUtils.parseDate(LocalDate.now().plusYears(years), formatDate.getValue());
    }


    /**
     * 获取当前日期的偏移量-年
     *
     * @param date  时间
     * @param years 偏移数量
     * @return
     */
    public static Long dayPlusYear(Long date, int years) {
        if (date > 100000000L) {
            LocalDateTime localDateTime = LocalDateTime.parse(String.valueOf(date), DateTimeFormatter.ofPattern(FormatDate.getValue(date.toString()).getValue())).plusDays(years);
            return DateHandleUtils.parseDateToLong(localDateTime, FormatDate.FORMAT_TIME_LONG.getValue());
        }
        return DateHandleUtils.parseDateToLong(
                LocalDate.parse(String.valueOf(date), DateTimeFormatter.ofPattern(FormatDate.getValue(date.toString()).getValue())).plusYears(years),
                FormatDate.FORMAT_DATE_LONG.getValue());
    }


    /**
     * 获取某一月日期的偏移量-年
     *
     * @param date  时间
     * @param years 偏移数量
     * @return
     */
    public static Long dayPlusYear(String date, int years) {
        if (date.trim().length() > 11) {
            LocalDateTime localDateTime = LocalDateTime.parse(date, DateTimeFormatter.ofPattern(FormatDate.getValue(date).getValue())).plusYears(years);
            return DateHandleUtils.parseDateToLong(localDateTime, FormatDate.FORMAT_TIME_LONG.getValue());
        }
        return DateHandleUtils.parseDateToLong(
                LocalDate.parse(date, DateTimeFormatter.ofPattern(FormatDate.getValue(date).getValue())).plusYears(years), FormatDate.FORMAT_DATE_LONG.getValue());
    }

    /**
     * 获取当前日期的偏移量-小时
     *
     * @param hours 偏移数量
     * @return
     */
    public static Long dayPlusHour(int hours) {
        return DateHandleUtils.parseDateToLong(LocalDateTime.now().plusHours(hours), FormatDate.FORMAT_DATE_LONG.getValue());
    }


    /**
     * 获取当前日期的偏移量-小时
     *
     * @param hours      偏移数量
     * @param formatDate 格式
     * @return
     */
    public static String dayPlusHour(int hours, FormatDate formatDate) {
        if (formatDate.getValue().trim().length() > 11) {
            return DateHandleUtils.parseDate(LocalDateTime.now().plusHours(hours), formatDate.getValue());
        }
        return DateHandleUtils.parseDate(LocalTime.now().plusHours(hours), formatDate.getValue());
    }

    /**
     * 获取某一日 的偏移量-小时
     *
     * @param date  时间
     * @param hours 偏移数量
     * @return
     */
    public static Long dayPlusHour(Long date, int hours) {
        if (date > 100000000L) {
            LocalDateTime localDateTime = LocalDateTime.parse(String.valueOf(date), DateTimeFormatter.ofPattern(FormatDate.getValue(date.toString()).getValue())).plusHours(hours);
            return DateHandleUtils.parseDateToLong(localDateTime, FormatDate.FORMAT_TIME_LONG.getValue());
        }
        return DateHandleUtils.parseDateToLong
                (LocalTime.parse(String.valueOf(date), DateTimeFormatter.ofPattern(FormatDate.getValue(date.toString()).getValue())).plusHours(hours), FormatDate.FORMAT_DATE_LONG.getValue());
    }


    /**
     * 获取当前日期的偏移量-小时
     *
     * @param date  时间
     * @param hours 偏移数量
     * @return
     */
    public static Long dayPlusHour(String date, int hours) {
        if (date.trim().length() > 11) {
            LocalDateTime localDateTime = LocalDateTime.parse(date, DateTimeFormatter.ofPattern(FormatDate.getValue(date).getValue())).plusHours(hours);
            return DateHandleUtils.parseDateToLong(localDateTime, FormatDate.FORMAT_TIME_LONG.getValue());
        }
        return DateHandleUtils.parseDateToLong
                (LocalTime.parse(date, DateTimeFormatter.ofPattern(FormatDate.getValue(date).getValue())).plusHours(hours), FormatDate.FORMAT_TIME_HOUR.getValue());
    }


    /**
     * 获取当前日期的偏移量-分钟
     *
     * @param minutes 偏移数量
     * @return
     */
    public static Long dayPlusMinute(int minutes) {
        return DateHandleUtils.parseDateToLong(LocalDateTime.now().plusMinutes(minutes), FormatDate.FORMAT_DATE_LONG.getValue());
    }

    /**
     * 获取当前日期的偏移量-分钟
     *
     * @param minutes    偏移数量
     * @param formatDate 格式
     * @return
     */
    public static String dayPlusMinute(int minutes, FormatDate formatDate) {
        if (formatDate.getValue().trim().length() > 11) {
            return DateHandleUtils.parseDate(LocalDateTime.now().plusMinutes(minutes), formatDate.getValue());
        }
        return DateHandleUtils.parseDate(LocalTime.now().plusMinutes(minutes), formatDate.getValue());
    }

    /**
     * 获取当前日期的偏移量-分钟
     *
     * @param date    时间
     * @param minutes 偏移数量
     * @return
     */
    public static Long dayPlusMinute(Long date, int minutes) {
        if (date > 100000000L) {
            LocalDateTime localDateTime = LocalDateTime.parse(String.valueOf(date), DateTimeFormatter.ofPattern(FormatDate.getValue(date.toString()).getValue())).plusMinutes(minutes);
            return DateHandleUtils.parseDateToLong(localDateTime, FormatDate.FORMAT_TIME_LONG.getValue());
        }
        return DateHandleUtils.parseDateToLong(
                LocalTime.parse(String.valueOf(date), DateTimeFormatter.ofPattern(FormatDate.getValue(date.toString()).getValue())).plusMinutes(minutes), FormatDate.FORMAT_TIME_HOUR.getValue());
    }


    /**
     * 获取当前日期的偏移量-分钟
     *
     * @param date    时间
     * @param minutes 偏移数量
     * @return
     */
    public static String dayPlusMinute(String date, int minutes) {
        if (date.trim().length() > 11) {
            LocalDateTime localDateTime = LocalDateTime.parse(date, DateTimeFormatter.ofPattern(FormatDate.getValue(date).getValue())).plusMinutes(minutes);
            return DateHandleUtils.parseDate(localDateTime, FormatDate.FORMAT_TIME_LONG.getValue());
        }
        return DateHandleUtils.parseDate(LocalTime.parse(date, DateTimeFormatter.ofPattern(FormatDate.getValue(date).getValue())).plusMinutes(minutes), FormatDate.FORMAT_DATE_LONG.getValue());
    }

    /**
     * 获取当前日期的偏移量-秒
     *
     * @param seconds 偏移数量
     * @return
     */
    public static Long dayPlusSecond(int seconds) {
        return DateHandleUtils.parseDateToLong(LocalDateTime.now().plusSeconds(seconds), FormatDate.FORMAT_DATE_LONG.getValue());
    }

    /**
     * 获取当前日期的偏移量-秒
     *
     * @param seconds    偏移数量
     * @param formatDate 时间
     * @return
     */
    public static String dayPlusSecond(int seconds, FormatDate formatDate) {
        if (formatDate.getValue().trim().length() > 11) {
            return DateHandleUtils.parseDate(LocalDateTime.now().plusSeconds(seconds), formatDate.getValue());
        }
        return DateHandleUtils.parseDate(LocalTime.now().plusSeconds(seconds), formatDate.getValue());
    }


    /**
     * 获取当前日期的偏移量-秒
     *
     * @param seconds 偏移数量
     * @param date    时间
     * @return
     */
    public static Long dayPlusSecond(Long date, int seconds) {
        if (date > 100000000L) {
            LocalDateTime localDateTime = LocalDateTime.parse(String.valueOf(date), DateTimeFormatter.ofPattern(FormatDate.getValue(date.toString()).getValue())).plusSeconds(seconds);
            return DateHandleUtils.parseDateToLong(localDateTime, FormatDate.FORMAT_TIME_LONG.getValue());
        }
        return DateHandleUtils.parseDateToLong(LocalTime.parse(String.valueOf(date), DateTimeFormatter.ofPattern(FormatDate.getValue(date.toString()).getValue())).plusSeconds(seconds), FormatDate.FORMAT_TIME_LONG.getValue());
    }


    /**
     * 获取当前日期的偏移量-秒
     *
     * @param seconds 偏移数量
     * @param date    时间
     * @return
     */
    public static String dayPlusSecond(String date, int seconds) {
        if (date.trim().length() > 11) {
            LocalDateTime localDateTime = LocalDateTime.parse(date, DateTimeFormatter.ofPattern(FormatDate.getValue(date).getValue())).plusSeconds(seconds);
            return DateHandleUtils.parseDate(localDateTime, FormatDate.FORMAT_TIME_LONG.getValue());
        }
        return DateHandleUtils.parseDate(LocalTime.parse(date, DateTimeFormatter.ofPattern(FormatDate.getValue(date).getValue())).plusSeconds(seconds), FormatDate.FORMAT_TIME_HOUR.getValue());
    }


    static class DateHandleUtils {

        /**
         * 计算今天一共有多少秒
         *
         * @return
         */
        public static Calendar getCalender() {
            Calendar curDate = Calendar.getInstance();
            return new GregorianCalendar(
                    curDate.get(Calendar.YEAR),
                    curDate.get(Calendar.MONTH),
                    curDate.get(Calendar.DATE) + 1, 0, 0, 0);
        }

        /**
         * 获取时间的毫秒数
         *
         * @param date 时间
         * @return
         */
        public static Long longToLocalDateTime(Long date) {
            Calendar calendar = Calendar.getInstance();
            if (date > 100000000L) {
                LocalDateTime time = LocalDateTime.parse(date.toString(), DateTimeFormatter.ofPattern(FormatDate.getValue(date.toString()).getValue()));
                calendar.set(DateTime.getYear(date),
                        DateTime.getMonth(date).getIndex() + 1,
                        DateTime.getDay(date),
                        time.getHour(),
                        time.getMinute(),
                        time.getSecond());
                return calendar.getTimeInMillis();
            } else if (date > 10000000L) {
                calendar.set(DateTime.getYear(date),
                        DateTime.getMonth(date).getIndex() + 1,
                        DateTime.getDay(date));
            } else if (date > 10000L) {
                calendar.set(DateTime.getYear(date),
                        DateTime.getMonth(date).getIndex() + 1);
                calendar.getTimeInMillis();
            }
            return calendar.getTimeInMillis();
        }

        /**
         * 日期转换 LocalDate
         *
         * @param date   时间
         * @param format 类型
         * @return
         */
        public static Long parseDateToLong(LocalDate date, String format) {
            return Long.parseLong(date.format(DateTimeFormatter.ofPattern(format)));
        }

        /**
         * 日期转换 LocalDateTime
         *
         * @param date   时间
         * @param format 类型
         * @return
         */
        public static Long parseDateToLong(LocalDateTime date, String format) {
            return Long.parseLong(date.format(DateTimeFormatter.ofPattern(format)));
        }

        /**
         * 日期转换 LocalTime
         *
         * @param date   时间
         * @param format 类型
         * @return
         */
        public static Long parseDateToLong(LocalTime date, String format) {
            return Long.parseLong(date.format(DateTimeFormatter.ofPattern(format)));
        }

        /**
         * 日期转换 LocalDate
         *
         * @param date   时间
         * @param format 类型
         * @return
         */
        public static String parseDate(LocalDate date, String format) {
            return date.format(DateTimeFormatter.ofPattern(format));
        }

        /**
         * 日期转换 LocalDateTime
         *
         * @param date   时间
         * @param format 类型
         * @return
         */
        public static String parseDate(LocalDateTime date, String format) {
            return date.format(DateTimeFormatter.ofPattern(format));
        }

        /**
         * 日期转换 LocalTime
         *
         * @param date   时间
         * @param format 类型
         * @return
         */
        public static String parseDate(LocalTime date, String format) {
            return date.format(DateTimeFormatter.ofPattern(format));
        }
    }
}
